﻿/*   
    Copyright (C) 2009 Galaktika Corporation ZAO

    This file is a part of Galaktika.BusinessMonitor
 
    Galaktika.BusinessMonitor is a free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
      
    You should have received a copy of the GNU General Public License
    along with Galaktika.BusinessMonitor.  If not, see <http://www.gnu.org/licenses/>.
  
    If GPL v.3 is not suitable for your products or company,
    Galaktika Corp provides Galaktika.BusinessMonitor under a flexible commercial license
    designed to meet your specific usage and distribution requirements.
    If you have already obtained a commercial license from Galaktika Corp,
    you can use this file under those license terms.
*/

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Ranet.AgOlap.Controls.MemberChoice;
using Galaktika.BI.Runtime.Services;
using System.ComponentModel;
using Galaktika.BI.Silverlight.Controls.General;
using System.Threading;
using Galaktika.BI.Runtime;
using System.Collections.Generic;
using Ranet.AgOlap.Controls.General;
using Galaktika.BI.Extensibility.Dom;
using Ranet.AgOlap.Controls.MemberChoice.ClientServer;
using Ranet.AgOlap.Commands;
using Ranet.Olap.Core;
using Ranet.Olap.Core.Data;
using Ranet.AgOlap.Controls.MemberChoice.Info;
using Ranet.AgOlap.Controls;

namespace Galaktika.BI.Silverlight.Controls.MemberChoice
{
    public class MemberChoicePopUpEx : MemberChoicePopUp, IBindableObject, IEditableObject
    {
        public MemberChoicePopUpEx()
        {
            base.Height = 18;
            MaxHeight = 18;
            MinHeight = 18;
            //m_Popup.SelectedItemTextBox.FontSize = 11;
        }

        protected override void BeforePopUp()
        {
            base.BeforePopUp();

            OlapDataLoaderEx loader = new OlapDataLoaderEx(this);
            loader.Context = this.Context;
            ChoiceControl.OlapDataLoader = loader;
        }

        protected override MemberChoiceControl GetChoiceControl()
        {
            MemberChoiceControl ctrl = base.GetChoiceControl();
            if (m_Context != null)
            {
                ctrl.LogManager = new LogManagerEx(m_Context);
            }
            return ctrl;
        }

        protected override void ApplySelection()
        {
            base.ApplySelection();

            try
            {
                //Сохраняем в глобальную переменную
                IUserTaskManager taskManager = (IUserTaskManager)Context.Services.GetService(typeof(IUserTaskManager));
                if (taskManager != null)
                {
                    taskManager.RunTaskAsync(String.Format(Localization.AppTask_ModificationVariable, AVariableToMDXSet), state => ModifyVariable(state), ChoiceControl.SelectedInfo);
                }

                ////Сохраняем в контекст информацию о выбранных элементах
                //if (this.Context.UserData != null)
                //    this.Context.UserData[this.Name + "_SelectedInfo"] = ChoiceControl.SelectedInfo;

                ////Сохраняем в глобальную переменную
                //IExecutionContext context = (IExecutionContext)this.Context.Services.GetService(typeof(IExecutionContext));
                //if (context != null && !String.IsNullOrEmpty(AVariableToMDXSet))
                //{
                //    ThreadPool.QueueUserWorkItem(new WaitCallback(
                //        state => context.ModifyVariable(this.Context, AVariableToMDXSet, set)));
                //}
            }
            catch (Exception ex)
            {
                LogManager.LogException(this.Name, ex);
            }
        }

        private void ModifyVariable(object state)
        {
            List<MemberChoiceSettings> settings = (List<MemberChoiceSettings>)state;

            String set = String.Empty;
            if (settings != null)
            {
                set = ChoiceControl.SelectedSet;
            }

            String uniqueName = String.Empty;
            String caption = String.Empty;
            if (settings != null &&
                settings.Count == 1 &&
                settings[0].SelectState == Ranet.AgOlap.Controls.MemberChoice.Info.SelectStates.Selected_Self)
            {
                uniqueName = settings[0].UniqueName;
                caption = settings[0].Caption;
            }

            String variableName = AVariableToMDXSet;
            IExecutionContext context = (IExecutionContext)this.Context.Services.GetService(typeof(IExecutionContext));
            if (context != null && !String.IsNullOrEmpty(variableName))
            {
                BrickVariable variable = context.GetVariable(this.Context, variableName);
                if (variable != null)
                {
                    context.ModifyVariable(this.Context, variableName, set);
                    variable.UserData[uniqueName] = caption;
                    variable.UserData[m_InternalName + "_SelectedInfo"] = ChoiceControl.SelectedInfo;
                }
            }
        }

        private String m_VariableToMDXSet = String.Empty;
        /// <summary>
        /// Глобальная переменная для MDXSet
        /// </summary>
        public String AVariableToMDXSet
        {
            set
            {
                m_VariableToMDXSet = value;
            }
            get
            {
                return m_VariableToMDXSet;
            }
        }

        #region IEditableObject Members

        public void BeginEdit()
        {
        }

        public void CancelEdit()
        {
        }

        public void EndEdit()
        {
            //NeedReload = true;
            //NeedReload = true;
            if (this.Context == null)
                return;

            if (Enum.IsDefined(typeof(MemberVisualizationTypes), AMemberVisualizationType))
            {
                base.MemberVisualizationType =
                    (MemberVisualizationTypes)Enum.Parse(
                        typeof(MemberVisualizationTypes),
                        AMemberVisualizationType,
                        true);
            }
            else
            {
                base.MemberVisualizationType = MemberVisualizationTypes.Caption;
            }

            ////Берем из контекста информацию о выбранных элементах
            //if (this.Context.UserData != null)
            //{
            //    object obj = null;
            //    this.Context.UserData.TryGetValue(AVariableToMDXSet, out obj);
            //    if (obj != null)
            //    {
            //        base.SelectedSet = obj.ToString();
            //    }
            //}
            base.SelectedSet = String.Empty;

            //Сохраняем в контекст информацию о выбранных элементах
            if (this.Context.UserData != null && this.Context.UserData.ContainsKey("_SelectedInfo"))
            {
                List<MemberChoiceSettings> selectedInfo = this.Context.UserData["_SelectedInfo"] as List<MemberChoiceSettings>;
                base.SelectedInfo = selectedInfo;
                if (selectedInfo != null)
                {
                    if (selectedInfo.Count > 1)
                    {
                        PopUpContainer.Text = Localization.Ctrl_Multiselect;
                    }
                    else
                    {
                        if (selectedInfo.Count > 0)
                        {
                            if (selectedInfo[0].SelectState != SelectStates.Selected_Self)
                                PopUpContainer.Text = Localization.Ctrl_Multiselect;
                            else
                                PopUpContainer.Text = selectedInfo[0].Caption;
                        }
                        else
                        {
                            PopUpContainer.Text = String.Empty;
                        }
                    }
                    return;
                }
            }

            IExecutionContext context = (IExecutionContext)this.Context.Services.GetService(typeof(IExecutionContext));
            if (context != null)
            {
                //Из глобальной переменной читаем имя выбранного 
                BrickVariable variable = context.GetVariable(this.Context, AVariableToMDXSet);
                if (variable != null)
                {
                    if (variable.UserData != null && variable.UserData.ContainsKey("_SelectedInfo"))
                    {
                        List<MemberChoiceSettings> selectedInfo = this.Context.UserData["_SelectedInfo"] as List<MemberChoiceSettings>;
                        base.SelectedInfo = selectedInfo;
                        if (selectedInfo != null)
                        {
                            if (selectedInfo.Count > 1)
                            {
                                PopUpContainer.Text = Localization.Ctrl_Multiselect;
                            }
                            else
                            {
                                if (selectedInfo.Count > 0)
                                {
                                    if (selectedInfo[0].SelectState != SelectStates.Selected_Self)
                                    {
                                        PopUpContainer.Text = Localization.Ctrl_Multiselect;
                                    }
                                    else
                                    {
                                        String txt = selectedInfo[0].Caption;
                                        if (selectedInfo[0].Info != null && selectedInfo[0].Info.Member != null)
                                        {
                                            txt = selectedInfo[0].Info.Member.GetText(MemberVisualizationType);
                                        }
                                        PopUpContainer.Text = txt;
                                    }
                                }
                                else
                                {
                                    PopUpContainer.Text = String.Empty;
                                }
                            }
                            return;
                        }
                    }
                    else
                    {
                        String value = variable.CurrentValue.Trim();
                        base.SelectedSet = value;
                        if (!String.IsNullOrEmpty(value))
                        {
                            String uniqueName = String.Empty;
                            if (value[0] != '{' && value[value.Length - 1] != '}')
                            {
                                uniqueName = value;
                                value = "{" + value + "}";
                            }
                            else
                            {
                                uniqueName = variable.CurrentValue.TrimStart('{');
                                uniqueName = uniqueName.TrimEnd('}');
                            }

                            //Пробуем найти в КЭШ предполагая что uniqueName у нас содержит уникальное имя
                            if (variable.UserData != null && variable.UserData.ContainsKey(uniqueName) && variable.UserData[uniqueName] is String)
                            {
                                PopUpContainer.Text = (String)variable.UserData[uniqueName];
                            }
                            else
                            {
                                //Если в КЭШ не найдено соответствие уникальному имени, то грузим из куба
                                // чтобы не моргало this.Dispatcher.BeginInvoke(delegate() { m_Popup.Text = String.Empty; });

                                OlapDataLoaderEx loader = new OlapDataLoaderEx(this);
                                loader.Context = this.Context;
                                loader.DataLoaded += new EventHandler<DataLoaderEventArgs>(loader_DataLoaded);

                                MemberChoiceQuery args = CommandHelper.CreateGetMembersArgs(AConnection, ACubeName, ASubCube, value);
                                loader.LoadData(args, variable);
                                return;
                            }
                        }
                    }
                }
            }

            // сохраняем имя переменную класса
            // для доступа к имени контрола из фонового потока
            // (метод Modifyvariable)
            m_InternalName = this.Name;
        }

        String m_MemberVisualizationType = String.Empty;
        /// <summary>
        /// Свойство для отображения в заголовках элементов
        /// </summary>
        public String AMemberVisualizationType
        {
            get { return m_MemberVisualizationType; }
            set { m_MemberVisualizationType = value; }
        }

        private string m_InternalName;

        void loader_DataLoaded(object sender, DataLoaderEventArgs e)
        {
            PopUpContainer.Text = String.Empty;
            if (e.Result.ContentType == InvokeContentType.Error)
            {
                LogManager.LogMessage(this.Name, e.Result.Content);
                return;
            }

            if (String.IsNullOrEmpty(e.Result.Content))
                return;

            List<MemberDataWrapper> members = XmlSerializationUtility.XmlStr2Obj<List<MemberDataWrapper>>(e.Result.Content);
            if (members != null)
            {
                if (members.Count == 1)
                {
                    PopUpContainer.Text = members[0].Member.GetText(MemberVisualizationType);
                }
                else
                {
                    PopUpContainer.Text = Localization.Ctrl_Multiselect; //"<Множественный выбор>";
                }

                BrickVariable variable = e.UserState as BrickVariable;
                if (variable != null)
                {
                    foreach (MemberDataWrapper member in members)
                    {
                        variable.UserData[member.Member.UniqueName] = member.Member.GetText(MemberVisualizationType);
                    }
                }
            }
        }

        #endregion

        #region IBindableObject Members

        IBindingContext m_Context = null;
        public IBindingContext Context
        {
            get
            {
                return m_Context;
            }
            set
            {
                m_Context = value;
                NeedReload = true;
                if (m_Context != null)
                {
                    base.LogManager = new LogManagerEx(m_Context);
                }
            }
        }


        private IDictionary<string, IBindingManager> m_Bindings;
        public IDictionary<string, IBindingManager> Bindings
        {
            get
            {
                if (m_Bindings == null)
                {
                    m_Bindings = new SafeDictionary<string, IBindingManager>();
                }

                return m_Bindings;
            }
        }

        #endregion


    }
}
